/*
 * Copyright 2008 - 2009 Lars Heuer (heuer[at]semagia.com). All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.semagia.atomico.server.impl.restlet;

import org.restlet.Application;
import org.restlet.Restlet;
import org.restlet.routing.Router;
import org.restlet.routing.Template;
import org.restlet.Request;
import org.restlet.Response;

import com.semagia.atomico.server.IConfiguration;
import com.semagia.atomico.server.IServerApplication;
import com.semagia.atomico.server.ServerApplication;
import com.semagia.atomico.server.ServerApplicationProvider;
import com.semagia.atomico.server.impl.restlet.resources.CollectionResource;
import com.semagia.atomico.server.impl.restlet.resources.FragmentResource;
import com.semagia.atomico.server.impl.restlet.resources.FragmentsResource;
import com.semagia.atomico.server.impl.restlet.resources.OverviewResource;
import com.semagia.atomico.server.impl.restlet.resources.SnapshotResource;
import com.semagia.atomico.server.impl.restlet.resources.SnapshotsResource;
import com.semagia.atomico.server.storage.IModifiableStorage;
import com.semagia.atomico.server.storage.IStorage;

/**
 * Atomico Server.
 * 
 * @author Lars Heuer (heuer[at]semagia.com) <a href="http://www.semagia.com/">Semagia</a>
 * @version $Rev: 90 $ - $Date: 2010-10-21 23:34:45 +0000 (Thu, 21 Oct 2010) $
 */
public final class AtomicoServerApplication extends Application implements IRestletServerConstants {

    private final IServerApplication _app;

    /**
     * Initializes an instance in the specified context <tt>app</tt>.
     *
     * @param app The {@link ServerApplication} context.
     */
    public AtomicoServerApplication() {
        super();
        _app = ServerApplicationProvider.getServerApplication();
    }

    /* (non-Javadoc)
     * @see org.restlet.Application#createRoot()
     */
    @Override
    public Restlet createInboundRoot() {
        final Router router = new Router(getContext());
        // Prevent that "/path" is also matched by "/path/"
        router.setDefaultMatchingMode(Template.MODE_EQUALS);
        final String collId = "{" + COLLECTION_ID + "}";
        final String fragmentId = "{" + FRAGMENT_ID + "}";
        final String snapshotId = "{" + SNAPSHOT_ID + "}";
        router.attach("/", OverviewResource.class);
        router.attach("/" + collId + "/" , CollectionResource.class);
        router.attach("/" + collId + "/snapshots/", SnapshotsResource.class);
        router.attach("/" + collId + "/snapshots/" + snapshotId, SnapshotResource.class);
        router.attach("/" + collId + "/fragments/", FragmentsResource.class);
        router.attach("/" + collId + "/fragments/" + fragmentId, FragmentResource.class);
        return router;
    }

    /* (non-Javadoc)
     * @see org.restlet.Application#handle(org.restlet.data.Request, org.restlet.data.Response)
     */
    @Override
    public void handle(Request request, Response response) {
        super.handle(request, response);
        response.getServerInfo().setAgent(APP_AGENT_SIG);
    }

    /**
     * Returns the {@link ServerApplication} instance bound to this.
     *
     * @return The server application context.
     */
    public IServerApplication getServerApplication() {
        return _app;
    }

    /**
     * Returns the {@link IStorage} instance.
     *
     * @return The {@link IStorage} instance.
     */
    public IStorage getStorage() {
        return _app.getStorage();
    }

    /**
     * Returns the {@link IModifiableStorage} instance or <tt>null</tt>.
     *
     * @return The {@link IModifiableStorage} instance or <tt>null</tt> if the
     *          storage is not modifiable.
     */
    public IModifiableStorage getModifiableStorage() {
        return _app.getModifiableStorage();
    }

    /**
     * Returns the {@link IConfiguration} instance.
     *
     * @return The {@link IConfiguration} instance.
     */
    public IConfiguration getConfiguration() {
        return _app.getConfiguration();
    }

    /* (non-Javadoc)
     * @see org.restlet.Application#getAuthor()
     */
    @Override
    public String getAuthor() {
        return APP_VENDOR;
    }

    /* (non-Javadoc)
     * @see org.restlet.Application#getName()
     */
    @Override
    public String getName() {
        return APP_NAME;
    }

}
